home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Files / Standard File / SettingUpStdFile / SettingUpStdFile.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  7.7 KB  |  258 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        SettingUpStdFile.c
  3.  
  4.     Contains:    This snippet demonstrates how to make Standard File
  5.                 select an initial file under both System 6 and System 7.
  6.                 (In this example, the System file will be selected.)
  7.     
  8.                 "An exhilirating snippet"
  9.                              - Nitin Ganatra
  10.  
  11.     Written by:  Greg Robbins    
  12.  
  13.     Copyright:    Copyright © 1993-1999 by Apple Computer, Inc., All Rights Reserved.
  14.  
  15.                 You may incorporate this Apple sample source code into your program(s) without
  16.                 restriction. This Apple sample source code has been provided "AS IS" and the
  17.                 responsibility for its operation is yours. You are not permitted to redistribute
  18.                 this Apple sample source code as "Apple sample source code" after having made
  19.                 changes. If you're going to re-distribute the source, we require that you make
  20.                 it clear in the source that the code was descended from Apple sample source
  21.                 code, but that you've made changes.
  22.  
  23.     Change History (most recent first):
  24.                 7/1/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  25.                             sfScript is reset in the System 7 DialogHook (below) to work  
  26.                             around a gotcha in Standard File that's incorrectly documented in  
  27.                             a New Inside Macintosh: Files sample.  See the DialogHook() function 
  28.                             for details.
  29.                 2/94        Nitin Ganatra    Compatible with the Universal Interfaces.
  30.                 
  31.  
  32. */
  33.  
  34. #include <QuickDraw.h>
  35. #include <StandardFile.h>
  36. #include <Fonts.h>
  37. #include <Menus.h>
  38. #include <Dialogs.h>
  39. #include <Events.h>
  40. #include <GestaltEqu.h>
  41. #include <TextEdit.h>
  42. #include <Errors.h>
  43. #include <OSEvents.h>
  44. #include <Folders.h>
  45. #include <Memory.h>
  46. #include <Script.h>
  47. #include <LowMem.h>
  48.  
  49. // prototypes
  50. pascal short DialogHook(short, DialogPtr , void *);
  51. pascal short OldDlgHook(short, DialogPtr);
  52. OSErr GetSystemFileSpec(FSSpecPtr);
  53.  
  54. // global struct for System 7 Std File dialog hook
  55. typedef struct {
  56.     StandardFileReply *theSFR;
  57.     FSSpec *itemSpec;
  58. } HookRecord, *HookRecordPtr;
  59.  
  60. // globals for System 6 Std File stuff
  61. StringPtr    gSelectFileName;
  62. short        gSelectFileCounter;
  63.  
  64.  
  65.  
  66.  
  67. void main(void)
  68. {
  69.     Point dialogPt;
  70.     SFTypeList mySFTypeList;
  71.     StandardFileReply mySFR;
  72.     SFReply oldSFR;
  73.     long procID;
  74.     FSSpec systemSpec;
  75.     HookRecord hookRec;
  76.     Boolean hasNewStdFileCallsFlag;
  77.     long gestResponse;
  78.     
  79.     OSErr retCode;
  80.     DlgHookYDUPP    myDlgHookUPP;
  81.  
  82.  
  83.     // initialize the toolbox
  84.     InitGraf(&qd.thePort); InitFonts(); InitWindows(); InitMenus();
  85.     TEInit(); InitDialogs(nil); InitCursor(); FlushEvents(everyEvent,0);
  86.  
  87.     // determine if the System 7 std file calls are available
  88.     retCode = Gestalt(gestaltStandardFileAttr, &gestResponse);
  89.     if (retCode == noErr && ((gestResponse >> gestaltStandardFile58) & 1) != 0)
  90.         hasNewStdFileCallsFlag = true;
  91.     else
  92.         hasNewStdFileCallsFlag = false;
  93.  
  94.     SetPt(&dialogPt, -1, -1);
  95.         
  96.     // get the FSSpec of the system file
  97.     retCode = GetSystemFileSpec(&systemSpec);
  98.     if (retCode != noErr) DebugStr((StringPtr)"\p GetSystemFileSpec failed");
  99.     
  100.     if (hasNewStdFileCallsFlag) {
  101.     
  102.         // System 7 method
  103.         
  104.         // point my hook data record at the reply record and at
  105.         // the file spec for the system file
  106.         
  107.         hookRec.itemSpec = &systemSpec;
  108.         hookRec.theSFR = &mySFR;
  109.  
  110.  
  111.         // Set up the universal proc pointer to your hook routine with this 
  112.         // macro defined in StandardFile.h.  **NOTE** This is different
  113.         // from the macro used for System 6 dialog hooks, and you should get
  114.         // a compiler error if you try to use the wrong UPP with the wrong call.
  115.         myDlgHookUPP = NewDlgHookYDProc(DialogHook);
  116.         
  117.         // call Std File
  118.         CustomGetFile(nil, -1, mySFTypeList, &mySFR, 0, dialogPt, myDlgHookUPP,
  119.             nil, nil, nil, &hookRec);
  120.             
  121.         // Dispose of the routine descriptor, since they do allocate memory..
  122.         DisposeRoutineDescriptor(myDlgHookUPP);
  123.  
  124.  
  125.     }
  126.     
  127.     else {
  128.         // System 6 method
  129.     
  130.         // stuff low memory to display the proper initial directory; 
  131.         // see Inside Mac:Files 3-31
  132.         
  133.         DlgHookUPP    myOldDlgHookUPP;
  134.         
  135.         // Throw out your SysEqu.h file and start using the low memory 
  136.         // accessor functions provided in LowMem.h.
  137.         LMSetSFSaveDisk(-systemSpec.vRefNum);
  138.         LMSetCurDirStore(systemSpec.parID);
  139.  
  140.         // set up the string for the system file name
  141.         gSelectFileName = systemSpec.name;
  142.  
  143.         // Set up the universal proc pointer to your hook routine with this 
  144.         // macro defined in StandardFile.h.  **NOTE** This is different
  145.         // from the macro used for System 7 dialog hooks, and you should get
  146.         // a compiler error if you try to use the wrong UPP with the wrong call.
  147.         myOldDlgHookUPP = NewDlgHookProc(OldDlgHook);
  148.         
  149.         // call Std File
  150.         SFGetFile(dialogPt, nil, nil, -1, mySFTypeList, myOldDlgHookUPP, &oldSFR);
  151.  
  152.         // Dispose of the routine descriptor, since they do allocate memory..
  153.         DisposeRoutineDescriptor(myOldDlgHookUPP);
  154.         
  155.         // store the result in a new reply record
  156.         mySFR.sfGood = oldSFR.good;
  157.         if (oldSFR.good) {
  158.         
  159.             // convert the WDRefNum and copy the name string
  160.             retCode = GetWDInfo(oldSFR.vRefNum, 
  161.                 &mySFR.sfFile.vRefNum, &mySFR.sfFile.parID, &procID);
  162.             BlockMove(oldSFR.fName, mySFR.sfFile.name, 1 + oldSFR.fName[0]);
  163.         }
  164.     }
  165. }
  166.  
  167. // this dialog hook for System 7 std file selects
  168. // the file specified by the hookRecord supplied as userData
  169.  
  170. pascal short DialogHook(short item, DialogPtr theDialog, 
  171.     void *userData)
  172. {
  173.     HookRecordPtr hookRecPtr;
  174.     
  175.     hookRecPtr = (HookRecordPtr) userData;
  176.     
  177.     // hookRecPtr->itemSpec points to the FSSpec of the item to be selected
  178.     // hookRecPtr->theSFR points to the standard file reply record
  179.  
  180.     // make sure we're dealing with the proper dialog
  181.     if (GetWRefCon(theDialog) == sfMainDialogRefCon) {
  182.     
  183.         // just when opening the dialog...
  184.         if (item == sfHookFirstCall) {
  185.     
  186.             // make the reply record hold the spec of the specified item
  187.             hookRecPtr->theSFR->sfFile = *hookRecPtr->itemSpec;
  188.             
  189.             // There’s a gotcha in Standard File when using sfHookChangeSelection. 
  190.             // Even though New Inside Macintosh: Files has a sample that doesn't set
  191.             // the sfScript field, it should be set, or the last object in the
  192.             // selected directory  will always be selected.
  193.             hookRecPtr->theSFR->sfScript = smSystemScript;
  194.  
  195.             // tell std file to change the selection to that item
  196.             item = sfHookChangeSelection;
  197.         }
  198.     }            
  199.         
  200.     return item;
  201. }
  202.  
  203.  
  204. // this std file dialog hook for System 6 selects the file
  205. // name in the global gSelectFileName
  206.  
  207. pascal short OldDlgHook(short item, DialogPtr theDialog)
  208. {
  209. #pragma unused (theDialog)
  210.     
  211.     // the idea here is to post keydown events, one per
  212.     // null hook-event, until the entire file name
  213.     // has been "typed" in (remember that the event queue
  214.     // is shorter than the maximum file name so we only post
  215.     // one key per null event)
  216.  
  217.     // reset the character counter initially
  218.     
  219.     if (item == sfHookFirstCall)
  220.         gSelectFileCounter = 0;
  221.         
  222.     // post one keyDown per null event until the string is exhausted
  223.     // This may not be a good idea for international software since 
  224.     // different input methods may be used.
  225.     // Instead, you may want to check the System version and temporarily 
  226.     // set the KeyScript to zero before doing these PostEvents.  
  227.     // Afterwards, set KeyScript back to its original mode.
  228.     else if (item == sfHookNullEvent) {
  229.         if (gSelectFileCounter < *gSelectFileName) {
  230.             gSelectFileCounter++;
  231.             PostEvent(keyDown, *(gSelectFileName+gSelectFileCounter));
  232.         }
  233.     }
  234.  
  235.     return item;
  236. }
  237.  
  238.  
  239. OSErr GetSystemFileSpec(FSSpecPtr systemSpec)
  240. {
  241.     // the System folder location is returned by FindFolder (or under
  242.     // System 6 by the compiler's FindFolder glue)
  243.     //
  244.     // the System file name is available in low-memory
  245.     
  246.     OSErr         retCode;
  247.     StringPtr    systemName;
  248.     
  249.     systemName = LMGetSysResName();        // Get the name of the System resource file
  250.  
  251.     retCode = FindFolder(kOnSystemDisk, kSystemFolderType, kCreateFolder,
  252.         &systemSpec->vRefNum, &systemSpec->parID);
  253.     if (retCode == noErr)
  254.         BlockMove((Ptr)systemName, systemSpec->name, systemName[0] + 1);
  255.     
  256.     return retCode;
  257. }
  258.